/* Driver template for the LEMON parser generator.
** The author disclaims copyright to this source code.
*/
/* First off, code is included that follows the "include" declaration
** in the input grammar file. */
#include <paxer/parser.h>

/* The next thing included is series of defines which control
** various aspects of the generated parser.
**    YYCODETYPE         is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 terminals
**                       and nonterminals.  "int" is used otherwise.
**    YYNOCODE           is a number of type YYCODETYPE which corresponds
**                       to no legal terminal or nonterminal number.  This
**                       number is used to fill in empty slots of the hash
**                       table.
**    LEMONPP_FALLBACK         If defined, this indicates that one or more tokens
**                       have fall-back values which should be used if the
**                       original value of the token will not parse.
**    YYACTIONTYPE       is the data type used for storing terminal
**                       and nonterminal numbers.  "unsigned char" is
**                       used if there are fewer than 250 rules and
**                       states combined.  "int" is used otherwise.
**    ParseTOKENTYPE     is the data type used for minor tokens given
**                       directly to the parser from the tokenizer.
**    YYNSTATE           the combined number of states.
**    YYNRULE            the number of rules in the grammar
**    YYERRORSYMBOL      is the code number of the error symbol.  If not
**                       defined, then do no error processing.
*/
//%%type defines%%
//%%non type defines%%
%%type defines%%
%%non type defines%%

/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define yytestcase() in the %include section
** to a macro that can assist in verifying code coverage.  For production
** code the yytestcase() macro should be turned off.  But it is useful
** for testing.
*/
#ifndef yytestcase
# define yytestcase(X)
#endif

/* Next are the tables used to determine what action to take based on the
** current state and lookahead token.  These tables are used to implement
** functions that take a state number and lookahead value and return an
** action integer.
**
** Suppose the action integer is N.  Then the action is determined as
** follows
**
**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
**                                      token onto the stack and goto state N.
**
**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
**
**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
**
**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
**
**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
**                                      slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
**      yy_action[ yy_shift_offset[S] + X ]
**
** If the index value yy_shift_offset[S]+X is out of range or if the value
** yy_lookahead[yy_shift_offset[S]+X] is not equal to X or if yy_shift_offset[S]
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
** and that yy_default(S) should be used instead.
**
** The formula above is for computing the action when the lookahead is
** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_offset() array is used in place of
** the yy_shift_offset[] array and YY_REDUCE_USE_DFLT is used in place of
** YY_SHIFT_USE_DFLT.
**
** The following are the tables generated in this section:
**
**  yy_action[]        A single table containing all actions.
**  yy_lookahead[]     A table containing the lookahead for each entry in
**                     yy_action.  Used to detect hash collisions.
**  yy_shift_offset[]    For each state, the offset into yy_action for
**                     shifting terminals.
**  yy_reduce_offset()   For each state, the offset into yy_action for
**                     shifting non-terminals after a reduce.
**  yy_default()       Default action for each state.
*/

/* The next table maps tokens into fallback tokens.  If a construct
** like the following:
**
**      %fallback ID X Y Z.
**
** appears in the grammar, then ID becomes a fallback token for X, Y,
** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
** but it does not parse, the type of the token is changed to ID and
** the parse is retried before an error is thrown.
*/

/* The following structure represents a single element of the
** parser's stack.  Information stored includes:
**
**   +  The state number for the parser at this level of the stack.
**
**   +  The value of the token stored at this level of the stack.
**      (In other words, the "major" token.)
**
**   +  The semantic value stored at this level of the stack.  This is
**      the information used by the action routines in the grammar.
**      It is sometimes called the "minor" token.
*/

LEMONPP_NS_BEGIN

class Parser::Imp {

    friend class Parser;

    typedef Parser::State State;
    typedef Parser::Code Code;
    typedef Parser::Rule Rule;
    typedef LEMONPP_ACTION_TYPE Action;
    typedef LEMONPP_SHIFT_TYPE Shift;
    typedef LEMONPP_REDUCE_TYPE Reduce;

    typedef Parser::NodeRef NodeRef;

    class Entry {
    public:
        State state_m;  /* The state-number */
        Code code_m;      /* The major token value.  This is the code
                             ** number for the token at this stack level */
        NodeRef nodeRef_m;     /* The user-supplied minor token value.  This
                             ** is the value of the token  */
        Entry(const State state,const Code token_code,const NodeRef & nodeRef);
        std::string longDescription() const;
    };
    typedef boost::shared_ptr<Entry> EntryRef;
    typedef std::deque<EntryRef> Stack;
    typedef Stack::size_type Size;

    class Const {
    public:
        enum Values {
            %%const enum%%
            kNULL=0
        };
    };

    Imp(const DriverRef & driverRef);

    int peak_m;                   /* Maximum value of yyidx */
    int error_step_m;             /* Shifts left before out of the error */

    Stack stack_m;                /* The parser's stack */
    DriverRef driverRef_m;

    class RuleInfo {
    public:
        typedef unsigned char RHSSize;
        Code lhs;         /* Code on the left-hand side token of the rule */
        RHSSize nrhs;             /* Number of right-hand side symbols in the rule */
    };

    static const RuleInfo ruleInfo(const Rule rule);

    static Action action(const State n);
    static Code lookahead(const State n);
    static Shift shift_offset(const State n);
    static Reduce reduce_offset(const State n);
    static Action defaultAction(const State n);

    void parse(
            const Code token_code,                 /* The major token code number */
            NodeRef & nodeRef       /* The value for the token */
            );

    void push(  const State state,               /* The new state to shift in */
                const Code token_code,                  /* The major token to shift in */
                const NodeRef & nodeRef         /* Pointer to the minor token to shift in */
            );
    bool pop(const Size n = 1);
    void reduce(const Rule rule_index);                /* Number of the rule by which to reduce */
    void accept(const NodeRef &candidateNodeRef);
    void parse_failed();
    void syntax_error (
            const Code token_code,                   /* The major type of the error token */
            const NodeRef & nodeRef            /* The minor type of the error token */
            );


    EntryRef entryRef(const int index) const; /* index >= 0; from the end, < 0 from the beginning */
    EntryRef entryRefAfterPop();

    State state(const int index) const;
    Code code(const int index) const;
    Parser::NodeRef & nodeRef(const int index) const; // raise if index is bad

    Action find_shift_action(
            const State current_state,
            const Code iLookAhead     /* The look-ahead token */
            ) const;
    Rule next_reduce_rule(State state,              /* Current state number */
                     Code iLookAhead     /* The look-ahead token */
            );

#ifdef LEMONPP_FALLBACK
    static const Code fallback(const Code n);
#endif
};
Parser::Parser(const DriverRef & driverRef)
    : imp_m(new Imp(driverRef)){}

Parser::Imp::Imp(const DriverRef & driverRef)
    : peak_m(0)
    , error_step_m(0)
    , driverRef_m(driverRef) { }

Parser::DriverRef Parser::driverRef() const {
    return imp_m->driverRef_m;
}

#ifdef LEMONPP_FALLBACK
const Parser::Code Parser::Imp::fallback(const Code n) {
    PaxerParameterAssert(n<Const::kFallbackCount);
    const Code x[] = {
        %%fallback tokens table%%
    0};
    return x[n];
}
#endif /* LEMONPP_FALLBACK */

const Parser::Imp::RuleInfo Parser::Imp::ruleInfo(const Rule n) {
    PaxerParameterAssert(n<Const::kActionCount);
    const RuleInfo x[] = {
        %%rule information table%%
        {0,0}};
    return x[n];
}

Parser::Imp::Action Parser::Imp::action(const State n) {
    PaxerParameterAssert(n<Const::kActionCount);
    const Action x[] = {
        %%action table%%
    0};
    return x[n];
}

Parser::Code Parser::Imp::lookahead(const Action n) {
    PaxerParameterAssert(n<Const::kActionCount);
    const Code x[] = {
        %%lookahead table%%
    0};
    return x[n];
}

Parser::Imp::Shift Parser::Imp::shift_offset(const State n) {
    PaxerParameterAssert(n<=Const::kShiftCount);// upper bound included
    const Shift x[] = {
        %%shift offset table%%
    0};
    return x[n];
}
Parser::Imp::Reduce Parser::Imp::reduce_offset(const State n) {
    PaxerParameterAssert(n<Const::kReduceCount);
    const Reduce x[] = {
        %%reduce offset table%%
    0};
    return x[n];
}
Parser::Imp::Action Parser::Imp::defaultAction(const State n) {
    PaxerParameterAssert(n<Parser::Const::kStateCount);
    const Action x[] = {
        %%default table%%
    0};
    return x[n];
}

#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required.  The following table supplies these names */
/* For tracing reduce actions, the names of all rules are required.
*/
const std::string Parser::tokenName(const Code code) {
    PaxerParameterAssert(code<Const::kTokenCount);
    const char *const names[] = {
    %%token name table%%
    ""};
    return names[code];
}

const std::string Parser::ruleName (const Rule rule) {
    PaxerParameterAssert(0<=rule);
    PaxerParameterAssert(rule<Const::kRuleCount);
    const char *const names[] = {
    %%rule name table%%
    ""};
    return names[rule];
}
#endif /* NDEBUG */

Parser::Imp::EntryRef Parser::Imp::entryRefAfterPop() {
    pop();
    return entryRef(0);
}

Parser::Imp::EntryRef Parser::Imp::entryRef(const int index) const {
    if (index<=0 && -index < stack_m.size()) {
        Stack::const_iterator it = stack_m.begin();
        it -= index;
        return *it;
    }
    if (index>0 && index <= stack_m.size()) {
        Stack::const_iterator it = stack_m.end();
        it -= index;
        return *it;
    }
    return EntryRef((EntryRef::element_type *)0);
}

Parser::NodeRef Parser::nodeRef(const int index) const {
    Imp::EntryRef eR = imp_m->entryRef(index);
    if (eR.get() != 0) {
        return eR->nodeRef_m;
    }
    return NodeRef((NodeRef::element_type *)0);
}

Parser::State Parser::Imp::state(const int index) const {
    EntryRef eR = entryRef(index);
    return eR.get()!=0 ? eR->state_m: Parser::Const::kDefaultState;
}
Parser::Code Parser::Imp::code(const int index) const {
    EntryRef eR = entryRef(index);
    return eR.get()!=0 ? eR->code_m: Parser::Const::kDefaultCode;
}
Parser::NodeRef & Parser::Imp::nodeRef(const int index) const {
    EntryRef eR = entryRef(index);
    return eR->nodeRef_m;// raise if bad
}

Parser::Imp::Entry::Entry(const State state
                   , const Code token_code
                   , const NodeRef & nodeRef)
    : state_m(state)
    , code_m(token_code)
    , nodeRef_m(nodeRef) {}

#define TO_UINT(__X)((unsigned int)(__X))
#define TO_INT(__X)((int)(__X))

std::string Parser::Imp::Entry::longDescription() const {
    std::ostringstream s;
    s<<"Entry state: "<<TO_UINT(state_m);
    s<<" code: "<<tokenName(code_m)<<"("<<TO_UINT(code_m)<<") ";
    s<<" node: ";
    s<<(nodeRef_m.get()? nodeRef_m->description(): "None");
    return s.str();
}

void Parser::Imp::push(const State state, /* The new state to shift in */
        const Code token_code,                  /* The major token to shift in */
        const NodeRef &nodeRef         /* Pointer to the minor token to shift in */
        ) {
#ifndef NDEBUG
    std::cout<<"?> "<<"Entering push "<<TO_UINT(state)<<std::endl;
    std::cout<<"?> "<<"Stack: "<<stack_m.size()<<std::endl;
    for (Stack::iterator it = stack_m.begin(); it!=stack_m.end(); ++it) {
        std::cout<<"?> "<<"...."<<it->get()->longDescription()<<std::endl;
    }
#endif
    EntryRef eR(new Entry(state,token_code,nodeRef));
    stack_m.push_front(eR);
    if( peak_m < stack_m.size() ){
        peak_m = stack_m.size();
    }
#ifndef NDEBUG
    std::cout<<"?> "<<"Exiting push"<<std::endl;
    std::cout<<"?> "<<"Stack: "<<stack_m.size()<<std::endl;
    for (Stack::iterator it = stack_m.begin(); it!=stack_m.end(); ++it) {
        std::cout<<"?> "<<"...."<<it->get()->longDescription()<<std::endl;
    }
#endif
}

/*
** Pop the parser's stack once.
**
** Return the major token number for the symbol popped.
*/
bool Parser::Imp::pop(const Size n) {
#ifndef NDEBUG
            std::cout<< "Popping " <<n<<" token(s)" << std::endl;
#endif
    Size i = n;
    while (i) {
        EntryRef eR = entryRef(0);
        if (eR.get()) {
#ifndef NDEBUG
            std::cout<< "Popping:" << std::endl;
            std::cout<< eR->longDescription() << std::endl;
#endif
            stack_m.pop_front();
        } else {
#ifndef NDEBUG
            std::cout<<"?> " << "No more entries to pop (" << i << " missing)" << std::endl;
#endif
            return false;
        }
        --i;
    }
    return true;
}

#ifndef NDEBUG
void Parser::activateTrace(std::ostream *out, const std::string & prompt) {
    log_m = out;
    prompt_m = prompt;
}
std::ostream& Parser::log() const{
    return (log_m? (* log_m):std::cout) << prompt_m;
}
#endif /* NDEBUG */

int Parser::peak() const {
    return imp_m->peak_m;
}

/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is Token::NonTerminal, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return Const::kActionNone.
**
** ** Suppose the action integer is N.  Then the action is determined as
** follows
**
**   0 <= N < YYNSTATE                  Shift N.  That is, push the lookahead
**                                      token onto the stack and goto state N.
**
**   YYNSTATE <= N < YYNSTATE+YYNRULE   Reduce by rule N-YYNSTATE.
**
**   N == YYNSTATE+YYNRULE              A syntax error has occurred.
**
**   N == YYNSTATE+YYNRULE+1            The parser accepts its input.
**
**   N == YYNSTATE+YYNRULE+2            No such action.  Denotes unused
**                                      slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as
**
**      yy_action[ yy_shift_offset[S] + X ]
**
** If the index value yy_shift_offset[S]+X is out of range or if the value
** yy_lookahead[yy_shift_offset[S]+X] is not equal to X or if yy_shift_offset[S]
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
** and that yy_default(S) should be used instead.
**
** The formula above is for computing the action when the lookahead is
** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_offset() array is used in place of
** the yy_shift_offset[] array and YY_REDUCE_USE_DFLT is used in place of
** YY_SHIFT_USE_DFLT.
**
*/
Parser::Imp::Action Parser::Imp::find_shift_action (
          const State state
        , const Code iLookAhead) const {
    std::cout << "find_shift_action" << std::endl;
    std::cout << "state: " << TO_UINT(state) << std::endl;
    std::cout << "lookahead: " << TO_UINT(iLookAhead) << std::endl;

    if( state>Const::kShiftCount ) {
        std::cout << "default action a..." << std::endl;
        return defaultAction(state);
    }
    int i = shift_offset(state);
    if( i==Const::kShiftUseDefault ){
        std::cout << "default action b..." << std::endl;
        return defaultAction(state);
    }
    assert( iLookAhead!=Token::NonTerminal );
    i += iLookAhead;
    if (i>=0 && i<Const::kActionCount && lookahead(i)==iLookAhead ) {
        std::cout << "action(" << i << ") = " << TO_INT(action(i)) << std::endl;
        return action(i);
    }
    if( iLookAhead>0 ){
#ifdef LEMONPP_FALLBACK
        Code iFallback;            /* Fallback token */
        if( iLookAhead<Const::kFallbackCount)
                && (iFallback = fallback(iLookAhead)!=0 ) {
#ifndef NDEBUG
            std::cout<<"?> "<<"FALLBACK "<<tokenName(iLookAhead)
                 <<" => "<< tokenName(iFallback)<<std::endl;
#endif
            return find_shift_action(state,iFallback);
        }
#endif
#ifdef YYWILDCARD
        {
            int j = i - iLookAhead + YYWILDCARD;
            if(
    #if YY_SHIFT_MIN+YYWILDCARD<0
                    j>=0 &&
    #endif
    #if YY_SHIFT_MAX+YYWILDCARD>=Const::kActionCount
                    j<Const::kActionCount &&
    #endif
                    lookahead(j)==YYWILDCARD
                    ){
#ifndef NDEBUG
                std::cout<<"?> "<<"WILDCARD "<<tokenName(iLookAhead)
                     <<" => "<< tokenName(YYWILDCARD)<<std::endl;
#endif /* NDEBUG */
                return action(j);
            }
        }
#endif /* YYWILDCARD */
    }
    std::cout << "default action (end)..." << std::endl;
    return defaultAction(state);
}

/*
** Find the appropriate action for a parser given the non-terminal
** look-ahead token iLookAhead.
**
** If the look-ahead token is Token::NonTerminal, then check to see if the action is
** independent of the look-ahead.  If it is, return the action, otherwise
** return Const::kActionNone.
*/
Parser::Imp::Rule Parser::Imp::next_reduce_rule(
        State state,              /* Current state number */
        Code iLookAhead     /* The look-ahead token */
        ) {
    int i;
#ifdef YYERRORSYMBOL
    if( state>Const::kReduceCount ){
        return defaultAction(state);
    }
#else
    assert( state<=Const::kReduceCount );
#endif
    i = reduce_offset(state);
    assert( i!=Const::kReduceUseDefault );
    assert( iLookAhead!=Parser::Token::NonTerminal );
    i += iLookAhead;
#ifdef YYERRORSYMBOL
    if( i<0 || i>=Const::kActionCount || lookahead(i)!=iLookAhead ){
        return defaultAction(state);
    }
#else
    assert( i>=0 && i<Const::kActionCount );
    assert( lookahead(i)==iLookAhead );
#endif
    return action(i);
}

/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
*/
void Parser::Imp::reduce(const Rule rule_index) {
#ifndef NDEBUG
    std::cout<<"?> "<<"Entering reduce rule: "<< ruleName(rule_index) << std::endl;
    std::cout<<"?> "<<"Stack: "<<stack_m.size()<<std::endl;
    for (Stack::iterator it = stack_m.begin(); it!=stack_m.end(); ++it) {
        std::cout<<"?> "<<"...."<<it->get()->longDescription()<<std::endl;
    }
#endif /* NDEBUG */

//  Exposed
    NodeRef reducedNodeRef;        /* The LHS of the rule reduced */
    std::cout << "Before the reduce rule: " << (reducedNodeRef.get()?reducedNodeRef->description():"None") << std::endl;
    switch( rule_index ) {
    /* Beginning here are the reduction cases.  A typical example
  ** follows:
  **   case 0:
  **  #line <lineno> <grammarfile>
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
#ifdef LEMONPP_LHS_MEMBER
#   error Change the macro name
#elif LEMONPP_RHS_STACK_MEMBER
#   error Change the macro name
#endif
#define LEMONPP_LHS_MEMBER reducedNodeRef
#define LEMONPP_RHS_STACK_MEMBER(__n) (nodeRef(__n))
%%reduce action code%%
#undef LEMONPP_LHS_MEMBER
#undef LEMONPP_RHS_STACK_MEMBER
    };
#ifndef NDEBUG
    std::cout << "After the reduce rule: ";
    std::cout << (reducedNodeRef.get()?reducedNodeRef->prettyType():"None");
    std::cout << ", ";
    std::cout << (reducedNodeRef.get()?reducedNodeRef->description():"None") << std::endl;
#endif
    PaxerAssert(pop(ruleInfo(rule_index).nrhs),std::runtime_error);
    State state = this->state(0);
    Code code = ruleInfo(rule_index).lhs;
    Rule next_rule_index = next_reduce_rule(state,code);
    if( next_rule_index < Parser::Const::kStateCount ){
        push(next_rule_index,code,reducedNodeRef);
    } else {
        assert( next_rule_index == Const::kActionAccept );
        std::cout << "Accepting: " << (reducedNodeRef.get()?reducedNodeRef->description():"None") << std::endl;
        accept(reducedNodeRef);
    }
    std::cout<<"?> "<<"Exiting reduce rule "<<std::endl;
    std::cout<<"?> "<<"Stack: "<<stack_m.size()<<std::endl;
    for (Stack::iterator it = stack_m.begin(); it!=stack_m.end(); ++it) {
        std::cout<<"?> "<<"...."<<it->get()->longDescription()<<std::endl;
    }
    std::cout<<"NEXT"<<std::endl;
}

/*
** The following code executes when a syntax error first occurs.
*/
void Parser::Imp::syntax_error (const Code token_code,                   /* The major type of the error token */
        const NodeRef & nodeRef            /* The minor type of the error token */
        ) {
    std::cerr << "Error parsing command"<< std::endl;
}

/*
** The following is executed when the parser accepts
*/
void Parser::Imp::accept(NodeRef const & candidateNodeRef) {
    NodeRef acceptedNodeRef(candidateNodeRef);
#ifndef NDEBUG
    std::cout<<"?> "<<"Accept! "<< (acceptedNodeRef.get()?acceptedNodeRef->description():"None") <<std::endl;
#endif
    /* Here code is inserted which will be executed whenever the
  ** parser accepts */
    %%accept code%%

    if (driverRef_m.get()!=0) {
        std::cout<<"?> "<<"Ask the driver to accept!"<<std::endl;
        driverRef_m->accept(acceptedNodeRef);
    } else {
        std::cout<<"?> "<<"NO DRIVER to accept!"<<std::endl;
    }
//    stack_m.clear(); NO
}

/* The main parser program.
** The first argument is a pointer to a structure obtained from
** "ParseAlloc" which describes the current state of the parser.
** The second argument is the major token number.  The third is
** the minor token.  The fourth optional argument is whatever the
** user wants (and specified in the grammar) and is available for
** use by the action routines.
**
** Inputs:
** <ul>
** <li> A pointer to the parser (an opaque structure.)
** <li> The major token number.
** <li> The minor token number.
** <li> An option argument of a grammar-specified type.
** </ul>
**
** Outputs:
** None.
*/
void Parser::parse(
        const Code token_code,                 /* The major token code number */
        NodeRef & nodeRef       /* The value for the token */
        ) {
#ifndef NDEBUG
    std::cout << "Start parsing: "<<std::endl;
    std::cout << "token code: " << TO_UINT(token_code) << "." << std::endl;
    std::cout << "token name: " << tokenName(token_code) << std::endl;
    std::cout << "noderef: " << (nodeRef.get()? nodeRef->description() :"None") << std::endl;
#endif

    bool once_again = true;
    bool end_of_input = (token_code==Token::EndOfInput);

#ifdef YYERRORSYMBOL
    bool on_error = false;   /* True if token_code has invoked an error */
#endif
    do {
        std::cout << "Entering the loop: "<<std::endl;
        const State state = imp_m->state(0);
        std::cout << "current state: " << TO_INT(state) <<std::endl;
        Imp::Action action = imp_m->find_shift_action(state,token_code);
        std::cout << "shift action: " << TO_UINT(action) <<std::endl;
        if ( action<Const::kStateCount ) {
            std::cout << "1 - Push" <<std::endl;
            assert( !end_of_input );  /* Impossible to shift the $ token */
            imp_m->push(action,token_code,nodeRef);
            --imp_m->error_step_m;
            return;
        } else if ( action < Imp::Const::kActionError ) {
            std::cout << "2 - Reduce with action: "<< TO_UINT(action-Const::kStateCount) <<std::endl;
            imp_m->reduce(action-Const::kStateCount);
            std::cout << "Done "<<std::endl;
            //continue;
        } else {
            std::cout << "3 - Error" <<std::endl;
            assert( action == Imp::Const::kActionError );
#ifndef NDEBUG
            std::cout<<"?> "<<"Syntax Error!"<<std::endl;
#endif
#ifdef YYERRORSYMBOL
            /* A syntax error has occurred.
          ** The response to an error depends upon whether or not the
          ** grammar defines an error token "ERROR".
          **
          ** This is what we do if the grammar does define ERROR:
          **
          **  * Call the %syntax_error function.
          **
          **  * Begin popping the stack until we enter a state where
          **    it is legal to shift the error symbol, then shift
          **    the error symbol.
          **
          **  * Set the error count to three.
          **
          **  * Begin accepting and shifting new tokens.  No new error
          **    processing will occur until three tokens have been
          **    shifted successfully.
          **
          */
            if( imp_m->error_step_m<0 ){
                imp_m->syntax_error(token_code,nodeRef);
            }
            if( eR.get()!=0 && eR->code_m==YYERRORSYMBOL || on_error ){
#ifndef NDEBUG
                std::cout<<"?> "<<"Discard input token "<<tokenName(token_code)<<std::endl;
#endif
                once_again = false;
            } else {
                do {
                    action = imp_m->next_reduce_rule(eR->state,YYERRORSYMBOL);
                } while (action >= Const::kStateCount
                       && (eR=entryRefAfterPop()).get() != 0);
                if( imp_m->stack_m.empty() || token_code==Token::NULL ) {
                    imp_m->parse_failed();
                    once_again = false;
                } else {
                    imp_m->push(action,YYERRORSYMBOL,NodeRef());
                }
            }
            imp_m->error_step_m = 3;
            on_error = true;
#elif defined(YYNOERRORRECOVERY)
            /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
      ** do any kind of error recovery.  Instead, simply invoke the syntax
      ** error routine and continue going as if nothing had happened.
      **
      ** Applications can set this macro (for example inside %include) if
      ** they intend to abandon the parse upon the first syntax error seen.
      */
            imp_m->syntax_error(token_code,nodeRef);
            break;

#else  /* YYERRORSYMBOL is not defined */
            /* This is what we do if the grammar does not define ERROR:
      **
      **  * Report an error message, and throw away the input token.
      **
      **  * If the input token is $, then fail the parse.
      **
      ** As before, subsequent error messages are suppressed until
      ** three input tokens have been successfully shifted.
      */
            if( imp_m->error_step_m<=0 ){
                imp_m->syntax_error(token_code,nodeRef);
            }
            imp_m->error_step_m = 3;
            if( end_of_input ){
                imp_m->parse_failed();
            }
            break;
#endif
        }
        std::cout << "End of iteration: "<<std::endl;
    } while( once_again && !imp_m->stack_m.empty() );
#ifndef NDEBUG
    std::cout << "End parsing: "<<std::endl;
    std::cout << "token code: " << TO_UINT(token_code) << "." << std::endl;
    std::cout << "token name: " << tokenName(token_code) << std::endl;
    std::cout << "noderef: " << (nodeRef.get()? nodeRef->description() :"None") << std::endl;
#endif
    return;
}
/*
** The following code executes when the parse fails
*/
#ifndef YYNOERRORRECOVERY
void Parser::Imp::parse_failed() {
#ifndef NDEBUG
    std::cout<<"?> "<<"Fail!"<<std::endl;
#endif
    /* Here code is inserted which will be executed whenever the
  ** parser fails */
    %%failure code%%
    stack_m.clear();
}
#endif /* YYNOERRORRECOVERY */

/* Conclude. On return the node parsed. Non void on success.
*/
Parser::NodeRef Parser::endInput() {
#warning NYI void return should be avoided ?
    NodeRef nR;
    parse(Token::EndOfInput, nR);
    std::cout << "Last input" << std::endl;
    if (imp_m->driverRef_m.get()!=0) {
        std::cout << "Calling driver" << std::endl;
        return imp_m->driverRef_m->nodeRef();
    }
    return NodeRef();
}

void Parser::restart() {
    imp_m->stack_m.clear();
    if (imp_m->driverRef_m.get()) {
       imp_m->driverRef_m->prepareParse();
    }
}

LEMONPP_NS_END

